package com.googlecode.wheres_my_stuff_okay_potato;

import java.io.Serializable;
import java.util.Date;

/**
 * Item is the information carrying class that holds the properties of lost and
 * found items.
 * 
 * @author Clay Anderson
 */
public abstract class Item implements Serializable {
	private static final long serialVersionUID = 4586078834545602593L;
	private String name, desc, loc;
	private boolean isOpen;
	private final User owner;
	private final Date dateCreated;
	private String category;

	// Must be implemented by subclasses:
	public abstract boolean isLostItem();

	public abstract boolean isFoundItem();

	/**
	 * Creates a new item with specified details.
	 * 
	 * @param name
	 *            is the name of the item.
	 * @param desc
	 *            is a description of the item.
	 * @param loc
	 *            is the location of the item.
	 * @param owner
	 *            is the user that owns this item.
	 */
	public Item(String name, String desc, String loc, User owner,
			String category) {
		this.name = name;
		this.desc = desc;
		this.loc = loc;
		this.owner = owner;
		this.category = category;

		isOpen = true;
		dateCreated = new Date();
	}

	/**
	 * Returns the name of this item.
	 * 
	 * @return the name of this item.
	 */
	public String getName() {
		return name;
	}

	/**
	 * Returns the description of this item.
	 * 
	 * @return the description of this item.
	 */
	public String getDesc() {
		return desc;
	}

	/**
	 * Returns the location of this item.
	 * 
	 * @return the location of this item.
	 */
	public String getLoc() {
		return loc;
	}

	/**
	 * Returns the owner of this item.
	 * 
	 * @return the owner of this item.
	 */
	public User getOwner() {
		return owner;
	}

	/**
	 * Checks of the specified user is the owner of this item.
	 * 
	 * @param user
	 *            is the user to be compared to the current item's owner.
	 * @return true if the specified user is the owner of this item; false
	 *         otherwise.
	 */
	public boolean ownedBy(User user) {
		return user.equals(owner);
	}

	/**
	 * Returns the date that this item was created.
	 * 
	 * @return the date that this item was created.
	 */
	public Date getDateCreated() {
		return dateCreated;
	}

	/**
	 * @param date
	 *            The date to be compared to
	 * @return true iff item was created after date parameter
	 */
	public boolean after(Date date) {
		return dateCreated.after(date);
	}

	/**
	 * @param date
	 *            The date to be compared to
	 * @return true iff item was created before date parameter
	 */
	public boolean before(Date date) {
		return dateCreated.before(date);
	}

	/**
	 * Returns whether or not this item is "open" - in other words, whether or
	 * not this item's status has been resolved.
	 * 
	 * @return true if this item's status has been resolved; false otherwise.
	 */
	public boolean isOpen() {
		return isOpen;
	}

	/**
	 * Closes this item. Sets this item's status to "closed."
	 */
	public void close() {
		isOpen = false;
	}

	public String getItemCategory() {
		return category;
	}

	public void setCategory(String category) {
		this.category = category;
	}

	@Override
	public String toString() {
		return ("Name: " + name + "; Open: " + isOpen + "; Date: "
				+ dateCreated.toString() + "; Category: " + category);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((category == null) ? 0 : category.hashCode());
		result = prime * result
				+ ((dateCreated == null) ? 0 : dateCreated.hashCode());
		result = prime * result + ((desc == null) ? 0 : desc.hashCode());
		result = prime * result + (isOpen ? 1231 : 1237);
		result = prime * result + ((loc == null) ? 0 : loc.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		// result = prime * result + ((owner == null) ? 0 : owner.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Item other = (Item) obj;
		if (category == null) {
			if (other.category != null)
				return false;
		} else if (!category.equals(other.category))
			return false;
		if (dateCreated == null) {
			if (other.dateCreated != null)
				return false;
		} else if (!dateCreated.equals(other.dateCreated))
			return false;
		if (desc == null) {
			if (other.desc != null)
				return false;
		} else if (!desc.equals(other.desc))
			return false;
		if (isOpen != other.isOpen)
			return false;
		if (loc == null) {
			if (other.loc != null)
				return false;
		} else if (!loc.equals(other.loc))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (owner == null) {
			if (other.owner != null)
				return false;
		} else if (!owner.equals(other.owner))
			return false;
		return true;
	}
}